<template>
    <div ref="wrapRef" :class="getWrapperClass">
        <BasicForm submitOnReset v-bind="getFormProps" v-if="getBindValues.useSearchForm" :tableAction="tableAction" @register="registerForm" @submit="handleSearchInfoChange" @advanced-change="redoHeight">
            <template #[replaceFormSlotKey(item)]="data" v-for="item in getFormSlotKeys">
                <slot :name="item" v-bind="data || {}"></slot>
            </template>
        </BasicForm>

        <Table ref="tableElRef" v-bind="getBindValues" :rowClassName="getRowClassName" v-show="getEmptyDataIsShowTable" @change="handleTableChange">
            <template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
                <slot :name="item" v-bind="data || {}"></slot>
            </template>

            <template #[`header-${column.dataIndex}`] v-for="column in columns" :key="column.dataIndex">
                <HeaderCell :column="column" />
            </template>
        </Table>
    </div>
</template>
<script lang="ts">
    import type {
        BasicTableProps,
        TableActionType,
        SizeType,
        ColumnChangeParam,
    } from './types/table';

    import { defineComponent, ref, computed, unref, toRaw, inject, watchEffect } from 'vue';
    import { Table } from 'ant-design-vue';
    import { BasicForm, useForm } from '/@/components/Form/index';
    import { PageWrapperFixedHeightKey } from '/@/components/Page';
    import expandIcon from './components/ExpandIcon';
    import HeaderCell from './components/HeaderCell.vue';
    import { InnerHandlers } from './types/table';
    import { usePagination } from './hooks/usePagination';
    import { useColumns } from './hooks/useColumns';
    import { useDataSource } from './hooks/useDataSource';
    import { useLoading } from './hooks/useLoading';
    import { useRowSelection } from './hooks/useRowSelection';
    import { useTableScroll } from './hooks/useTableScroll';
    import { useCustomRow } from './hooks/useCustomRow';
    import { useTableStyle } from './hooks/useTableStyle';
    import { useTableHeader } from './hooks/useTableHeader';
    import { useTableExpand } from './hooks/useTableExpand';
    import { createTableContext } from './hooks/useTableContext';
    import { useTableFooter } from './hooks/useTableFooter';
    import { useTableForm } from './hooks/useTableForm';
    import { useDesign } from '/@/hooks/web/useDesign';

    import { omit } from 'lodash-es';
    import { basicProps } from './props';
    import { isFunction } from '/@/utils/is';
    import { warn } from '/@/utils/log';

    export default defineComponent({
        components: {
            Table,
            BasicForm,
            HeaderCell,
        },
        props: basicProps,
        emits: [
            'fetch-success',
            'fetch-error',
            'selection-change',
            'register',
            'row-click',
            'row-dbClick',
            'row-contextmenu',
            'row-mouseenter',
            'row-mouseleave',
            'edit-end',
            'edit-cancel',
            'edit-row-end',
            'edit-change',
            'expanded-rows-change',
            'change',
            'columns-change',
            'table-redo',
        ],
        setup(props, { attrs, emit, slots, expose }) {
            const tableElRef = ref(null);
            const tableData = ref<Recordable[]>([]);

            const wrapRef = ref(null);
            const innerPropsRef = ref<Partial<BasicTableProps>>();

            const { prefixCls } = useDesign('basic-table');
            const [registerForm, formActions] = useForm();

            const getProps = computed(() => {
                return { ...props, ...unref(innerPropsRef) } as BasicTableProps;
            });

            const isFixedHeightPage = inject(PageWrapperFixedHeightKey, false);
            watchEffect(() => {
                unref(isFixedHeightPage) &&
                props.canResize &&
                warn(
                    "'canResize' of BasicTable may not work in PageWrapper with 'fixedHeight' (especially in hot updates)"
                );
            });

            const { getLoading, setLoading } = useLoading(getProps);
            const {
                getPaginationInfo,
                getPagination,
                setPagination,
                setShowPagination,
                getShowPagination,
            } = usePagination(getProps);

            const {
                getRowSelection,
                getRowSelectionRef,
                getSelectRows,
                clearSelectedRowKeys,
                getSelectRowKeys,
                deleteSelectRowByKey,
                setSelectedRowKeys,
            } = useRowSelection(getProps, tableData, emit);

            const {
                handleTableChange: onTableChange,
                getDataSourceRef,
                getDataSource,
                getRawDataSource,
                setTableData,
                updateTableDataRecord,
                deleteTableDataRecord,
                insertTableDataRecord,
                findTableDataRecord,
                fetch,
                getRowKey,
                reload,
                getAutoCreateKey,
                updateTableData,
            } = useDataSource(
                getProps,
                {
                    tableData,
                    getPaginationInfo,
                    setLoading,
                    setPagination,
                    getFieldsValue: formActions.getFieldsValue,
                    clearSelectedRowKeys,
                },
                emit
            );

            function handleTableChange(...args) {
                onTableChange.call(undefined, ...args);
                emit('change', ...args);
                // 解决通过useTable注册onChange时不起作用的问题
                const { onChange } = unref(getProps);
                onChange && isFunction(onChange) && onChange.call(undefined, ...args);
            }

            const {
                getViewColumns,
                getColumns,
                setCacheColumnsByField,
                setColumns,
                getColumnsRef,
                getCacheColumns,
            } = useColumns(getProps, getPaginationInfo);

            const { getScrollRef, redoHeight } = useTableScroll(
                getProps,
                tableElRef,
                getColumnsRef,
                getRowSelectionRef,
                getDataSourceRef
            );

            const { customRow } = useCustomRow(getProps, {
                setSelectedRowKeys,
                getSelectRowKeys,
                clearSelectedRowKeys,
                getAutoCreateKey,
                emit,
            });

            const { getRowClassName } = useTableStyle(getProps, prefixCls);

            const { getExpandOption, expandAll, collapseAll } = useTableExpand(getProps, tableData, emit);

            const handlers: InnerHandlers = {
                onColumnsChange: (data: ColumnChangeParam[]) => {
                    emit('columns-change', data);
                    // support useTable
                    unref(getProps).onColumnsChange?.(data);
                },
            };

            const { getHeaderProps } = useTableHeader(getProps, slots, handlers);

            const { getFooterProps } = useTableFooter(
                getProps,
                getScrollRef,
                tableElRef,
                getDataSourceRef
            );

            const { getFormProps, replaceFormSlotKey, getFormSlotKeys, handleSearchInfoChange } =
                useTableForm(getProps, slots, fetch, getLoading);

            const getBindValues = computed(() => {
                const dataSource = unref(getDataSourceRef);
                let propsData: Recordable = {
                    // ...(dataSource.length === 0 ? { getPopupContainer: () => document.body } : {}),
                    ...attrs,
                    customRow,
                    //树列表展开使用AntDesignVue默认的加减图标 author:scott date:20210914
                    //expandIcon: slots.expandIcon ? null : expandIcon(),
                    ...unref(getProps),
                    ...unref(getHeaderProps),
                    scroll: unref(getScrollRef),
                    loading: unref(getLoading),
                    tableLayout: 'fixed',
                    rowSelection: unref(getRowSelectionRef),
                    rowKey: unref(getRowKey),
                    columns: toRaw(unref(getViewColumns)),
                    pagination: toRaw(unref(getPaginationInfo)),
                    dataSource,
                    footer: unref(getFooterProps),
                    ...unref(getExpandOption),
                };
                if (slots.expandedRowRender) {
                    propsData = omit(propsData, 'scroll');
                }

                propsData = omit(propsData, ['class', 'onChange']);
                return propsData;
            });

            const getWrapperClass = computed(() => {
                const values = unref(getBindValues);
                return [
                    prefixCls,
                    attrs.class,
                    {
                        [`${prefixCls}-form-container`]: values.useSearchForm,
                        [`${prefixCls}--inset`]: values.inset,
                    },
                ];
            });

            const getEmptyDataIsShowTable = computed(() => {
                const { emptyDataIsShowTable, useSearchForm } = unref(getProps);
                if (emptyDataIsShowTable || !useSearchForm) {
                    return true;
                }
                return !!unref(getDataSourceRef).length;
            });

            function setProps(props: Partial<BasicTableProps>) {
                innerPropsRef.value = { ...unref(innerPropsRef), ...props };
            }

            const tableAction: TableActionType = {
                reload,
                getSelectRows,
                clearSelectedRowKeys,
                getSelectRowKeys,
                deleteSelectRowByKey,
                setPagination,
                setTableData,
                updateTableDataRecord,
                deleteTableDataRecord,
                insertTableDataRecord,
                findTableDataRecord,
                redoHeight,
                setSelectedRowKeys,
                setColumns,
                setLoading,
                getDataSource,
                getRawDataSource,
                setProps,
                getRowSelection,
                getPaginationRef: getPagination,
                getColumns,
                getCacheColumns,
                emit,
                updateTableData,
                setShowPagination,
                getShowPagination,
                setCacheColumnsByField,
                expandAll,
                collapseAll,
                getSize: () => {
                    return unref(getBindValues).size as SizeType;
                },
            };
            createTableContext({ ...tableAction, wrapRef, getBindValues });

            expose(tableAction);

            emit('register', tableAction, formActions);

            return {
                tableElRef,
                getBindValues,
                getLoading,
                registerForm,
                handleSearchInfoChange,
                getEmptyDataIsShowTable,
                handleTableChange,
                getRowClassName,
                wrapRef,
                tableAction,
                redoHeight,
                getFormProps: getFormProps as any,
                replaceFormSlotKey,
                getFormSlotKeys,
                getWrapperClass,
                columns: getViewColumns,
            };
        },
    });
</script>
<style lang="less">
    @border-color: #cecece4d;

    @prefix-cls: ~'@{namespace}-basic-table';

    [data-theme='dark'] {
        .ant-table-tbody > tr:hover.ant-table-row-selected > td,
        .ant-table-tbody > tr.ant-table-row-selected td {
            background-color: #262626;
        }

      .@{prefix-cls} {
        //表格选择工具栏样式
        .alert {
          background-color: #323232;
          border-color: #424242;
        }
      }
    }

    .@{prefix-cls} {
        max-width: 100%;

        &-row__striped {
            td {
                background-color: @app-content-background;
            }
        }

        &-form-container {
            padding: 10px;

            .ant-form {
                padding: 12px 10px 6px 10px;
                margin-bottom: 8px;
                background-color: @component-background;
                border-radius: 2px;
            }
        }

        .ant-tag {
            margin-right: 0;
        }

        .ant-table-wrapper {
            padding: 6px;
            background-color: @component-background;
            border-radius: 2px;

            .ant-table-title {
                min-height: 40px;
                padding: 0 0 8px 0 !important;
            }

            .ant-table.ant-table-bordered .ant-table-title {
                border: none !important;
            }
        }

        .ant-table {
            width: 100%;
            overflow-x: hidden;

            &-title {
                display: flex;
                padding: 8px 6px;
                border-bottom: none;
                justify-content: space-between;
                align-items: center;
            }
            //定义行颜色
            .trcolor{
              background-color: rgba(255, 192, 203, 0.31);
              color:red;
            }

            //.ant-table-tbody > tr.ant-table-row-selected td {
            //background-color: fade(@primary-color, 8%) !important;
            //}
        }

        .ant-pagination {
            margin: 10px 0 0 0;
        }

        .ant-table-footer {
            padding: 0;

            .ant-table-wrapper {
                padding: 0;
            }

            table {
                border: none !important;
            }

            .ant-table-body {
                overflow-x: hidden !important;
                //  overflow-y: scroll !important;
            }

            td {
                padding: 12px 8px;
            }
        }
        //表格选择工具栏样式
        .alert {
            height: 38px;
            background-color: #f3f3f3;
            border-color: #e3e3e3;
        }
        &--inset {
          .ant-table-wrapper {
            padding: 0;
          }
        }
    }
</style>
